package com.example.jimuyutabletcontrol.network.udp;

import java.net.InetAddress;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author: HDX
 * @date: 2020\4\27 0027
 */
public abstract class ISocket {
    /**
     * 缓存大小
     */
    public static final int BUFFER_LENGTH = 10240;

    /**
     * 字节缓冲区
     */
    protected byte[] byteBuffer = new byte[BUFFER_LENGTH];

    /**
     * 缓存大小
     */
    protected int receiveBuffer;

    /**
     * 使用剩余内存的百分比
     */
    private static final double MEMORY_USE_RATIO = 0.5;

    protected List<UdpMessageCallback> messageCallbacks;

    private static final int POOL_SIZE = 5;

    protected ExecutorService availableThreadPool;

    public ISocket() {
        availableThreadPool = Executors.newFixedThreadPool(
                Runtime.getRuntime().availableProcessors() * POOL_SIZE);
        receiveBuffer = (int) (Runtime.getRuntime().freeMemory() * MEMORY_USE_RATIO);
        messageCallbacks = new ArrayList<>();
    }

    public void setMessageCallback(UdpMessageHandle handle) {
        if (null == handle) return;
        if (messageCallbacks.contains(handle)) return;
        messageCallbacks.add(handle);
    }

    public void removeMessageCallback(UdpMessageHandle handle) {
        if (null == handle) return;
        if (!messageCallbacks.contains(handle)) return;
        messageCallbacks.remove(handle);
    }

    public void removeMessageCallback(UdpMessageCallback callback) {
        if (null == callback || null == messageCallbacks || messageCallbacks.size() == 0) return;
        boolean isHas = false;
        int position = -1;
        for (UdpMessageCallback messageCallback : messageCallbacks) {
            if (messageCallback instanceof UdpMessageHandle) {
                UdpMessageCallback udpMessageCallback = ((UdpMessageHandle) messageCallback).getUdpMessageCallback();
                if (null != udpMessageCallback && callback == udpMessageCallback) {
                    isHas = true;
                    position = messageCallbacks.indexOf(messageCallback);
                    break;
                }
            }
        }
        if (isHas && position != -1) {
            messageCallbacks.remove(position);
        }
    }

    public void removeAllMessageCallback() {
        messageCallbacks.clear();
    }

    protected void callbackData(String message) {
        if (null == messageCallbacks || messageCallbacks.size() == 0) return;
        for (UdpMessageCallback callback : messageCallbacks) {
            callback.onMessage(message);
        }
    }

    public abstract void init();

    public abstract void sendMessage(String message);

    public abstract void sendMessage(String message, InetAddress inetAddress, int Port);

    public abstract boolean isThreadRunning();

    public abstract void release();
}
